home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / KeyMacros / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-19  |  4.8 KB  |  195 lines  |  [TEXT/CWIE]

  1. // Program Author: Paul Baxter 
  2. // pbaxter@assistivetech.com
  3. //
  4.  
  5. #include <DeskBus.h>
  6. #include "ShowInit.h"
  7.  
  8.  
  9. #ifndef powerc
  10. #pragma error Sorry this only works on a real machine
  11. #endif
  12.  
  13. #define kKeyBoardADBAddress            2
  14.  
  15. #define kIconID                        128
  16. #define kNoInstallID                129
  17.  
  18. #define kKeyStateMask                0x80
  19. #define kValueMask                    0x7F
  20.  
  21.  
  22. #define kNumKeys                    129
  23.  
  24. // Where is this defined??
  25. extern    ADBInitUPP JADBProc : 0x06B8;
  26.  
  27. ADBInitUPP    gOldADBInitProc;
  28. ADBServiceRoutineUPP gKeyBoardServiceRoutine = nil;
  29. ADBServiceRoutineUPP gOldKeyBoardServiceRoutine = nil;
  30. ADBDataBlock gKeyBoardADBinfo;
  31.  
  32. extern Boolean InstallServiceRoutines(void);
  33. extern void InstallJADBProc(void);
  34. extern void MyADBInitProc(SInt8 callOrder);
  35. extern  pascal void ADBKeyBoardServiceRoutine(Ptr buffer, TempADBServiceRoutineUPP completionProc,  long refCon, long command);
  36. extern Boolean ExpandedMacro(char ch, Boolean up);
  37. extern void LoadMacros(void);
  38.  
  39. #ifdef powerc
  40.     // for Metrowerks' linker, this defines the interface for main().
  41.     ProcInfoType __procinfo = kCStackBased | RESULT_SIZE(kNoByteCode);
  42. #endif
  43.  
  44. Handle gMacros[kNumKeys];
  45.  
  46. // Main entry point
  47. void main(void)
  48. {
  49.     Handle ourhandle;
  50.     Boolean InstalledOK = false;
  51.     THz    pZone;
  52.  
  53.     pZone = GetZone();
  54.     SetZone(SystemZone());
  55.     ourhandle = Get1IndResource('INIT', 1);
  56.     if (ourhandle)  {
  57.         DetachResource(ourhandle);
  58.         HLock(ourhandle);
  59.         HNoPurge(ourhandle);
  60.  
  61.         LoadMacros();
  62.  
  63.         // take over the ADBServiceRoutine for the KeyBoard
  64.         InstalledOK = InstallServiceRoutines();
  65.         if (InstalledOK) {
  66.             // Install a JADBProc so we don't go away after a ADBReInit
  67.             InstallJADBProc();
  68.         }
  69.  
  70.     }
  71.     if (InstalledOK)
  72.         ShowINIT(kIconID, -1);
  73.     else
  74.         ShowINIT(kNoInstallID, -1);
  75.  
  76.     SetZone(pZone);
  77. }
  78.  
  79. // Setup our service routines
  80. Boolean InstallServiceRoutines(void)
  81. {
  82.     long adbaddr;
  83.     ADBDataBlock adb_data;
  84.     ADBSetInfoBlock setADBInfo;
  85.     short adbcount, adbindex;
  86.     OSErr err;
  87.  
  88.     err = -1;
  89.     adbcount = CountADBs();
  90.     for (adbindex = 1; adbindex <= adbcount; adbindex++) {
  91.         adbaddr = GetIndADB(&adb_data,adbindex);
  92.     
  93.         if ((adb_data.origADBAddr == kKeyBoardADBAddress)) {
  94.             BlockMoveData(&adb_data, &gKeyBoardADBinfo, sizeof(ADBDataBlock));
  95.             // Remember we will be called once to install and twice during each ADBReInit
  96.             if (!gKeyBoardServiceRoutine) {
  97.                 gKeyBoardServiceRoutine = NewADBServiceRoutineProc(ADBKeyBoardServiceRoutine);
  98.             }
  99.             if (!gKeyBoardServiceRoutine)
  100.                 return err == noErr;
  101.  
  102.             gOldKeyBoardServiceRoutine = adb_data.dbServiceRtPtr;
  103.             setADBInfo.siService = gKeyBoardServiceRoutine;
  104.             setADBInfo.siDataAreaAddr = adb_data.dbDataAreaAddr;
  105.  
  106.             err = SetADBInfo(&setADBInfo, adbaddr);
  107.             break;
  108.         }
  109.     }
  110.     return err == noErr;
  111. }
  112.  
  113. // Install a JADBProc callback for before and after ADBReInit
  114. void InstallJADBProc(void)
  115. {
  116.     ADBInitUPP ourADBInitProc;
  117.  
  118.     gOldADBInitProc = JADBProc;
  119.     ourADBInitProc = NewADBInitProc(MyADBInitProc);
  120.     JADBProc = ourADBInitProc;
  121. }
  122.  
  123.  
  124. void LoadMacros(void)
  125. {
  126.     short count, index, rfile, macroId;
  127.     Handle theHandle;
  128.     ResType rType;
  129.     Str255    rName;
  130.  
  131.     for (count = 0; count < kNumKeys; count++) {
  132.         gMacros[count] = nil;
  133.     }
  134.  
  135.     rfile = CurResFile();
  136.     count = Count1Resources('KMAC');
  137.     for (index = 1; index <= count; index++) {
  138.         UseResFile(rfile);
  139.         theHandle = Get1IndResource('KMAC', index);
  140.         if (theHandle) {
  141.             HLock(theHandle);
  142.             GetResInfo(theHandle, ¯oId, &rType, rName);
  143.             gMacros[macroId] = theHandle;
  144.             DetachResource(theHandle);
  145.         }
  146.     }
  147.  
  148. }
  149.  
  150. // Handler for KeyBoard service routine
  151. pascal void ADBKeyBoardServiceRoutine(Ptr buffer, TempADBServiceRoutineUPP completionProc, long refCon, long command)
  152. {
  153. #pragma unused (refCon)
  154.     unsigned char keyupstate, count, macrosize, macroindex;
  155.     Ptr macroPtr;
  156.     char mybuffer[3],ch;
  157.  
  158.     for (count = 0; count < buffer[0]; count++) {
  159.         // high most bit is the key state
  160.         if (buffer[count + 1] != 0xFF) {
  161.             keyupstate = buffer[count + 1] & kKeyStateMask;
  162.             ch = buffer[count + 1] & kValueMask;            
  163.             if (gMacros[ch]) {
  164.                 buffer[count + 1] = 0xFF;            // say that there is no data
  165.                 if (keyupstate == false) {
  166.                     macroPtr = *gMacros[ch];
  167.                     macrosize = *(short*)macroPtr;
  168.                     macroPtr += sizeof(short);
  169.                     for (macroindex = 0; macroindex < macrosize; macroindex ++) {
  170.                         mybuffer[0] = 2;
  171.                         mybuffer[1] = macroPtr[macroindex * 2]  & kValueMask;
  172.                         if (macroPtr[(macroindex * 2) + 1]) {
  173.                             mybuffer[1] |= kKeyStateMask;
  174.                         }
  175.                         mybuffer[2] = 0xFF;
  176.                         CallADBServiceRoutineProc(gOldKeyBoardServiceRoutine, mybuffer, nil, (long)gKeyBoardADBinfo.dbDataAreaAddr, command);
  177.                     }                
  178.                 }
  179.             }
  180.  
  181.         }
  182.     }
  183.     CallADBServiceRoutineProc(gOldKeyBoardServiceRoutine, buffer, completionProc, (long)gKeyBoardADBinfo.dbDataAreaAddr, command);
  184. }
  185.  
  186.  
  187. // needed to re-install our service routine
  188. void MyADBInitProc(SInt8 callOrder)
  189. {
  190.     Boolean        InstallOK;
  191.  
  192.     CallADBInitProc(gOldADBInitProc, callOrder);
  193.     if (callOrder)
  194.         InstallOK = InstallServiceRoutines();
  195. }